package com.lehezn.opensource.appkit.ControlModule;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Map;

/**
 * Created by es-ll on 17/10/5.
 */

public class Codec {
    /**
     * 03
     * 01
     * 00 00 17 01 09 00 27
     * 10 01 00
     * 03 30 30 30 00 00 00 00 00 00 00 00 00 00 00 00
     * 01
     * 03 00 08 03 70 50 00
     * 00 00 00
     * 04 31 31 32 32 00 00 00 00 00 00 00 00 00 00 00
     * 01
     * 77 66 55 44 33 22 00
     * 00 00 00
     * 0F E4 BA 8C E6 A5 BC E4 B8 9C E6 88 BF E9 97 00
     * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

     * 表信息：表数量1B+执行1B+地址7B+表类型1B+波特率1B+混合1B+名称16B，最多16个表（27B *8+1=217B）
     * 混合 bit0 峰谷  bit1-bit3 通道
     * 执行:01新增,02删除,03修改,04不变，
     * 表数量（高3位）：0：正常下发操作表数据；1：读取实时数据，2：读取当前数据；3：读取日冻结；4：读取月冻结
     */
    public static Map<String, MeterInfo> decodeMeterInfo(byte[] data, Map<String, MeterInfo> map) {
        if (data == null) {
            return map;
        }
        MyLog.d("decodeMeterInfo-->" + Util.bytesToHexString(data));
        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
        byte len = byteBuffer.get();//表数量
        if(len>>>5!=0){
            return map;
        }

        MyLog.d("decodeMeterInfo--Len=" + len);
        for (int i = 0; i < len; i++) {
            MeterInfo meterInfo = new MeterInfo();

            byte action = byteBuffer.get();

            byte[] addr = new byte[7];
            byteBuffer.get(addr);
            meterInfo.addr = addr;
            String addrStr = Util.bytesToHexString(Util.revertOrder(addr));
            meterInfo.addrStr = addrStr;

            meterInfo.type = byteBuffer.get();//类型
            meterInfo.baud = byteBuffer.get();//波特率
//            meterInfo.parity = byteBuffer.get();//奇偶
//            meterInfo.isSanxiang=byteBuffer.get()==0;//是否三项
//            meterInfo.isPeakvall = byteBuffer.get() == 0;//支持峰谷

            byte mix = byteBuffer.get();
            int peek = mix & 0x01;
            MyLog.d("peek=" + peek);
            int channel = mix >> 1;
            MyLog.d("channel=" + channel);
            meterInfo.isPeakvall = (peek == 0);
            meterInfo.channel = (byte) channel;

            byte[] name = new byte[16];
            byteBuffer.get(name);
            ByteBuffer nameBuffer = ByteBuffer.wrap(name);

            byte nameLen = nameBuffer.get();
            if (nameLen >= 15 || nameLen <= 0) {
                nameLen = 15;
            }
            byte[] nameArr = new byte[nameLen];
            nameBuffer.get(nameArr);
            try {
                meterInfo.name = new String(nameArr,"utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            if (action == Util.ACTION_DELETE) {
                map.remove(addrStr);
            } else {

                map.put(addrStr, meterInfo);
            }
            MyLog.d("meterinfolist-->" + meterInfo.toString());
        }
        return map;

    }
    // 表数量（高3位）：0：正常下发操作表数据；1：读取实时数据，2：读取当前数据；3：读取日冻结；4：读取月冻结

    public static  void handleLen(byte len){
        int hight=len>>>5;


    }
//01-16 16:16:48.222 31419-31419/com.gizwits.opensource.appkit D/EneryTag: decodeMeterRtData-->
// 02 11 22 33 44 55 66 20
// 00
// 10 00电压
// 00 10 00电流
// 00 00  01 有功功率
// 00 10 功率因素
// 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

// 04 00 03 00 08 03 70 00
// 00类型
// 00 00电压
// 00 00 00电流
// 00 00 00有功功率
// 00 00功率因数
// 00 00 00 00 00 00 00
// 00 03 00 08 03 70 50
// 00
// 00 82
// 21 00 00
// 00 00 00
//
// 04 00 03 00 08 03 70 00
// 00
// 00 00
// 00 00 00
// 00 00 00
// 00 00
// 00 00 00 00 00 00 00 00
// 03 00 08 03 70 50 00
// 00 16 22 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
//
// 04 00 03 00 08 03 70 00
// 00 00 00 00 00 00 00 00 00
// 00 00
// 00
// 00 00 00 00 00 00 00
// 03 00 08 03 70 50 00
// 00 86 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


    /**
     * 电表实时数据：表数量1B+表地址7B+表类型1B+电压2B+电流3B+有功功率3B+功率因素2B  （18B）单相表 最多8个
     * 或 表地址7B+表类型1B+电压6B+电流9B+有功功率9B+功率因素6B   三相表  （38B）  最多5个三相表 225B
     *
     * 电表实时数据：表数量1B+表地址7B+表类型1B+电压2B+电流3B+有功功率3B+功率因素2B  （18B）单相表 最多8个
     或 表地址7B+表类型1B+电压6B+电流9B+有功功率9B+功率因素6B   三相表  （38B）  最多5个三相表 225B
     */
    public static Map<String, MeterInfo> decodeMeterRtData(byte[] data, Map<String, MeterInfo> map) {
        if (data == null) {
            return map;
        }
        MyLog.d("decodeMeterRtData-->" + Util.bytesToHexString(data));

        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
        byte len = byteBuffer.get();
        for (int i = 0; i < len; i++) {
            byte[] addr = new byte[7];
            byteBuffer.get(addr);//表地址
            String addrStr = Util.bytesToHexString(Util.revertOrder(addr));
            MeterInfo meterInfo = map.get(addrStr);
            if (meterInfo == null) {
                meterInfo = new MeterInfo();
                meterInfo.addrStr = addrStr;
            }
            byte type = byteBuffer.get();
            if (type == Util.TYPE_SINGLE_METER) {
                byte[] volArr = new byte[2];
                byteBuffer.get(volArr);
                meterInfo.vol = Util.getVol(volArr) + "";

                byte[] curArr = new byte[3];
                byteBuffer.get(curArr);
                meterInfo.cur = Util.getCur(curArr) + "";

                byte[] powerArr = new byte[3];
                byteBuffer.get(powerArr);
                meterInfo.power = Util.getPower(powerArr) + "";

                byte[] powerFactoryArr = new byte[2];
                byteBuffer.get(powerFactoryArr);
                meterInfo.powerFactory = Util.getPowerFactory(powerFactoryArr) + "";
            } else if (type == Util.TYPE_MUTIL_METER) {
                for (int k = 0; k < 3; k++) {
                    byte[] volArr = new byte[2];
                    byteBuffer.get(volArr);
                    meterInfo.vol += Util.getVol(volArr) + "/";
                }
                for (int k = 0; k < 3; k++) {
                    byte[] curArr = new byte[3];
                    byteBuffer.get(curArr);
                    meterInfo.cur += Util.getCur(curArr) + "/";
                }
                for (int k = 0; k < 3; k++) {
                    byte[] powerArr = new byte[3];
                    byteBuffer.get(powerArr);
                    meterInfo.power += Util.getPower(powerArr) + "/";

                }
                for (int k = 0; k < 3; k++) {
                    byte[] powerFactoryArr = new byte[2];
                    byteBuffer.get(powerFactoryArr);
                    meterInfo.powerFactory = Util.getPowerFactory(powerFactoryArr) + "/";
                }
            }
            MyLog.d("decodeMeterRtData2-->" + meterInfo.toString());
        }

        return map;
    }


    /**
     * 02 00 00 17 01 09 00 27
     * 10
     * 00 67 20 05 2C
     * 00 67 20 05 2C
     * 00 00 0
     *
     * 04 00 03 00 08 03 70 00
     * 00
     * 00 00 00 00正向有功电量4B
     * 00 00 00 00尖4B+
     * 00 00 00 00峰4B
     * 00 00 00 00平4B
     * 00 00 00 00谷4B
     * 00 00 00 00
     * 00 00 00 00
     * 27 00 09 01 17 00 00
     * 10
     * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     * 03 00 08 03 70 50 00
     * 00
     * 74 20 13 00
     * 00 00 00 00
     * 00 00 00 00
     * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     * 00 00 17 01 09 00 27 10 00 00 00 00
     *
     * 04 00 03 00 08 03 70 00
     * 00
     * 00 00 00 00
     * 00 00 00 00
     * 00 00 00 00
     * 00 00 00 00
     * 00 00 00 00
     * 00 00 00 00
     * 00 00 00 00
     * 27 00 09 01 17 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 08 03 70 50 00 00 74 20 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 01 09 00 27 10 00 00 00 00 00 00 00 00
     *
     * 04 00 03 00 08 03 70 00
     * 00 00 00 00
     * 00 00 00 00
     * 00 00 00 00
     * 00 00 00 00
     * 00 00 00 00
     * 00 00 00 00
     * 00 00 00 00 00
     * 27 00 09 01 17 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 08 03 70 50 00 00 74 20 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 01 09 00 27 10 00 00
     *
     * 表当前示数：表数量1B   表地址7B +表类型1B+正向有功电量4B + 尖4B+峰4B+平4B + 谷4B (1B + 28B*8个=225B)
     * 表地址7B +表类型1B+ 累计流量5B + 结算日累计流量5B + 当前时间7B + 状态2B +1B（dummy）   水表、气表
     * 表地址7B +表类型1B+ 结算日热量5B + 当前热量5B +   供水温度3B + 回水温度3B +状态2B + 2B（dummy）  热表
     *
     * @param data
     * @return
     */
    public static Map<String, MeterInfo> decodeMeterForwardFum(byte[] data, Map<String, MeterInfo> map) {
        if (data == null) {
            return map;
        }
        MyLog.d("decodeMeterForwardFum-->" + Util.bytesToHexString(data));

        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
        byte len = byteBuffer.get();

        for (int i = 0; i < len; i++) {
            byte[] addr = new byte[7];
            byteBuffer.get(addr);
            String addrStr = getAddr(addr);

            MeterInfo meterInfo = map.get(addrStr);
            if (meterInfo == null) {
                meterInfo = new MeterInfo();
                meterInfo.addrStr = addrStr;

            }
            byte type = byteBuffer.get();
            if (type == Util.TYPE_SINGLE_METER || type == Util.TYPE_MUTIL_METER) {
                byte[] enery0Arr = new byte[4];
                byteBuffer.get(enery0Arr);
                byte[] enery1Arr = new byte[4];
                byteBuffer.get(enery1Arr);
                byte[] enery2Arr = new byte[4];
                byteBuffer.get(enery2Arr);
                byte[] enery3Arr = new byte[4];
                byteBuffer.get(enery3Arr);
                byte[] enery4Arr = new byte[4];
                byteBuffer.get(enery4Arr);
                meterInfo.enery = Util.getEleEnery(enery0Arr);
                meterInfo.enery0 = Util.getEleEnery(enery1Arr);
                meterInfo.enery1 = Util.getEleEnery(enery2Arr);
                meterInfo.enery2 = Util.getEleEnery(enery3Arr);
                meterInfo.enery3 = Util.getEleEnery(enery4Arr);
            } else if (type == Util.TYPE_WATER || type == Util.TYPE_GOS) {
// 表地址7B +表类型1B+ 累计流量5B + 结算日累计流量5B + 当前时间7B + 状态2B +1B（dummy）   水表、气表

                byte[] enery0Arr = new byte[4];
                byteBuffer.get(enery0Arr);//累计流量
                meterInfo.enery = Util.getWaterEnery(enery0Arr);
                byteBuffer.get(enery0Arr);//结算日累计流量

                byte[] timeArr = new byte[7];
                byteBuffer.get(timeArr);//当前时间
                byte[] status=new byte[2];
                byteBuffer.get(status);//状态
                byteBuffer.get();//dummy

            } else if (type == Util.TYPE_HEAT) {
//表地址7B +表类型1B+ 结算日热量5B + 当前热量5B +   供水温度3B + 回水温度3B +状态2B + 2B（dummy）  热表

                byte[] enery0Arr = new byte[4];
                byteBuffer.get(enery0Arr);//结算日热量

                meterInfo.enery = Util.getHeatEnery(enery0Arr);
                byteBuffer.get(enery0Arr);//当前热量

                byte[] arr = new byte[3];
                byteBuffer.get(arr);//供水温度
                byteBuffer.get(arr);//回水温度
                byte[] status=new byte[2];
                byteBuffer.get(status);//状态
                byteBuffer.get();//dummy
            }
            MyLog.d("decodeMeterForwardFum2-->" + meterInfo.toString());

        }
        return map;
    }


    /**
     * 表状态信息：表地址、在线、抄读成功率、故障
     * 表状态信息：表数量1B + 表地址（7B）+ 表类型1B+ 在线（1B）+ 抄读成功率（1B）+ 故障（1B） +其它（4B）,数据长度 121B =  1B + 15B*8
     */
    public static Map<String, MeterInfo> decodeMeterStatus(byte[] data, Map<String, MeterInfo> map) {

        if (data == null) {
            return map;
        }
        MyLog.d("decodeMeterStatus-->" + Util.bytesToHexString(data));

        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);

        byte num = byteBuffer.get();//表数量

        for (int i = 0; i < num; i++) {

            byte[] addr = new byte[7];
            byteBuffer.get(addr);//表地址
            String addrStr = Util.bytesToHexString(Util.revertOrder(addr));

            MeterInfo meterInfo = map.get(addrStr);
            if (meterInfo == null) {
                meterInfo = new MeterInfo();
                meterInfo.addrStr = addrStr;

            }
            meterInfo.addr = addr;
            meterInfo.type = byteBuffer.get();
            meterInfo.online = byteBuffer.get();
            meterInfo.successPercent = byteBuffer.get();
            meterInfo.error = byteBuffer.get();
            byte[] other = new byte[4];
            byteBuffer.get(other);
            MyLog.d("decodeMeterStatus1-->" + meterInfo.toString());

        }
        return map;
    }


    //非单字节的数据格式是啥？？
    // 表地址
    // 电量有没有小数点，是大段还是小段？？
    //

    /**
     * 据冻结，冻结12个月。
     * 表数量（1B）+  表地址(7B)+ 表类型1B + 3月数据冻结（20Byte= 4 *3 +8B  20*8 +1 = 161B ）。最多8个表(默认上报3个月，APP可以主动拉取12个月数据)  30日数据格式见后面
     表地址(7B) + 表类型1B+ 12个月数据冻结（长度和电表一致）,   水表、气表
     表地址(7B) + 表类型1B+ 12个月数据冻结（长度和电表一致）,    热表
     表数量1B 高3位表示拉取的月数， 0 ：3个月， 1：12个月

     04
     00 03 00 08 03 70 00
     00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     27 00 09 01 17 00 00
     10
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     03 00 08 03 70 50 00
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     00 00 17 01 09 00 27
     10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

     */
    public static Map<String, MeterInfo> decodeDataFreezeMonth(byte[] month, Map<String, MeterInfo> map) {

        if (month == null) {
            return map;
        }
        MyLog.d("decodeDataFreezeMonth-->" + Util.bytesToHexString(month));

        ByteBuffer byteBuffer = ByteBuffer.wrap(month);
        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);

        byte len = byteBuffer.get();//  len是电表个

        int arrayLen;
        int pullDays=len>>>5;
        if (pullDays==0){
            arrayLen=12;
        }else {
            arrayLen=12;
        }
        len= (byte) (len&0x1F);

        for (int i = 0; i < len; i++) {
            byte[] addr = new byte[7];
            byteBuffer.get(addr);//表地址
            String addrStr = Util.bytesToHexString(Util.revertOrder(addr));
            byteBuffer.get();//表类型

            MeterInfo meterInfo = map.get(addrStr);
            if (meterInfo == null) {
                meterInfo = new MeterInfo();
                meterInfo.addrStr = addrStr;

            }
            double[] freezedata = new double[arrayLen];//数据不够12个月的会补齐？目前按照都是12个来解析
            for (int j = 0; j < arrayLen; j++) {
                if (meterInfo.type == Util.TYPE_SINGLE_METER || meterInfo.type == Util.TYPE_MUTIL_METER) {
                    byte[] ele = new byte[4];
                    byteBuffer.get(ele);
                    freezedata[j] = Util.getEleEnery(ele);
                } else if (meterInfo.type == Util.TYPE_WATER || meterInfo.type == Util.TYPE_GOS) {
                    byte[] enery0Arr = new byte[4];
                    byteBuffer.get(enery0Arr);

                    freezedata[j] = Util.getWaterEnery(enery0Arr);
                } else if (meterInfo.type == Util.TYPE_HEAT) {
                    byte[] enery0Arr = new byte[4];
                    byteBuffer.get(enery0Arr);

                    freezedata[j] = Util.getHeatEnery(enery0Arr);
                }

            }
            double[] tempData=new double[arrayLen];
            tempData[arrayLen-1]=freezedata[arrayLen-1];//最小的数不需要处理,处理数据为0的
            for (int m=arrayLen-2;m>=0;m--){
                if (freezedata[m]==0){
                    tempData[m]=tempData[m+1];
                }else {
                    tempData[m]=freezedata[m];
                }
            }
            MyLog.d("decodeDataFreezeMonth处理0之后-->" + Arrays.toString(tempData));

            double[] data = new double[arrayLen];// 第一个存放的是示数，之后是相减的值
            data[0] = ComputeUtil.sub(meterInfo.enery,tempData[0]);
            for (int k = 1; k < arrayLen; k++) {
                data[k] = ComputeUtil.sub(tempData[k-1] ,tempData[k]);
            }
            meterInfo.freezeMonth = data;
            MyLog.d("decodeDataFreezeMonth相减之后-->" + Arrays.toString( meterInfo.freezeMonth));

            MyLog.d("decodeDataFreezeMonth-->" + meterInfo.toString());

        }
        return map;

    }

    /**
     * 日数据冻结,长度（1B）+ 表地址(7B) + 30日数据冻结（120Byte= 4 *30）, 最多12个表
     *
     * 日数据冻结,表数量（1B）+ 表地址(7B) + 表类型1B+ 7日数据冻结（ 36 Byte= 4 *7 + 8B, 36*8 + 1= 289B ）,
     * 电表日冻结数据，(默认上报7日，APP可以主动拉取30日数据)  30日数据格式见后面
     *
     表数量（1B）+ 表地址(7B) + 表类型1B+ 7日冻结数据（ 长度和电表一致）,     水表、气表
     表数量（1B）+表地址(7B) + 表类型1B+ 7日数据冻结（长度和电表一致）,    热表

     表数量1B 高3位表示拉取的天数， 0 ：7日， 1：30日

     02 03 00 08 03 70 50 00
     00
     74 20 13 00
     74 20 13 00
     74 20 13 00
     00
     04
     00 03 00 08 03 70 00
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     27 00 09 01 17 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     03 00 08 03 70 50 00 00 74 20 13 00 74 20 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 01 09 00 27 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     02 00 00 17 01 09 00 27
     10
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     03 00 08 03 70 50
     00 00 00 00
     00
     00 77 20 13
     00 77 20 13
     00 76 20 13
     00 76 20 13
     00 76 20 13
     00 75 20 13
     00 75 20 13
     00 75 20 13
     00 74 20 13 00 74 20 13 00 74 20 13 00 74 20 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0

     02 00 00 17 01 09 00 27
     10
     00 67 20 05
     00 67 20 05
     00 00 00 00
     00 67 20 05
     00 67 20 05
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     03 00 08 03 70 50
     00
     00 78 20 13
     00 78 20 13
     00 00 00 00
     00 77 20 13
     00 77 20 13
     00 00 00 00
     00 77 20 13
     00 77 20 13
     00 76 20 13
     00 76 20 13
     00 76 20 13
     00 75 20 13
     00 75 20 13
     00 75 20 13 00 74 20 13 00 74 20 13 00 74 20 13 00 74 20 13 00 00 00

     * @param day
     * @return
     */
    public static Map<String, MeterInfo> decodeDataFreezeDay(byte[] day, Map<String, MeterInfo> map) {

        if (day == null) {
            return map;
        }
        MyLog.d("decodeDataFreezeDay-->" + Util.bytesToHexString(day));

        ByteBuffer byteBuffer = ByteBuffer.wrap(day);
        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
        byte len = byteBuffer.get();//len是电表个数，不能是数据总长度，255不能满足总长度

        int arrayLen;
        int pullDays=len>>>5;
        if (pullDays==0){
            arrayLen=30;
        }else {
            arrayLen=30;
        }
        len= (byte) (len&0x1F);
        for (int i = 0; i < len; i++) {

            byte[] addr = new byte[7];
            byteBuffer.get(addr);//表地址
            byteBuffer.get();//表类型
            String addrStr = Util.bytesToHexString(Util.revertOrder(addr));

            MeterInfo meterInfo = map.get(addrStr);
            if (meterInfo == null) {
                meterInfo = new MeterInfo();
                meterInfo.addrStr = addrStr;

            }
            double[] freezedata = new double[arrayLen];// 数据不够12个月的会补齐？
            for (int j = 0; j < arrayLen; j++) {
                if (meterInfo.type == Util.TYPE_SINGLE_METER || meterInfo.type == Util.TYPE_MUTIL_METER) {
                    byte[] ele = new byte[4];
                    byteBuffer.get(ele);
                    freezedata[j] = Util.getEleEnery(ele);
                } else if (meterInfo.type == Util.TYPE_WATER || meterInfo.type == Util.TYPE_GOS) {
                    byte[] enery0Arr = new byte[4];
                    byteBuffer.get(enery0Arr);

                    freezedata[j] = Util.getWaterEnery(enery0Arr);
                } else if (meterInfo.type == Util.TYPE_HEAT) {
                    byte[] enery0Arr = new byte[4];
                    byteBuffer.get(enery0Arr);

                    freezedata[j] = Util.getHeatEnery(enery0Arr);
                }

            }
            double[] tempData=new double[arrayLen];
            tempData[arrayLen-1]=freezedata[arrayLen-1];//最小的数不需要处理,处理数据为0的
            for (int m=arrayLen-2;m>=0;m--){
                if (freezedata[m]==0){
                    tempData[m]=tempData[m+1];
                }else {
                    tempData[m]=freezedata[m];
                }
            }
            MyLog.d("decodeDataFreezeDay处理0之后-->" + Arrays.toString(tempData));


            double[] data = new double[arrayLen];// 第一个存放的是示数，之后是相减的值
            data[0] = ComputeUtil.sub(meterInfo.enery,tempData[0]);
            for (int k = 1; k < arrayLen; k++) {
                data[k] = ComputeUtil.sub(tempData[k-1], tempData[k]);
            }
            meterInfo.freezeDay = data;
            MyLog.d("decodeDataFreezeDay相减之后-->" + Arrays.toString(meterInfo.freezeDay));

            MyLog.d("decodeDataFreezeDay-->" + meterInfo.toString());

        }
        return map;
    }


    /**
     * 表信息：表数量1B+执行1B+地址7B+表类型1B+波特率1B+峰谷1B+通道1B+名称16B，最多16个表（27B *8+1=217B）
     */
    public static byte[] deletMeterInfo(MeterInfo meterInfo) {

        ByteBuffer byteBuffer = ByteBuffer.allocate(29);
        byte len = 1;
        byteBuffer.put(len);

        byte action = Util.ACTION_DELETE;
        byteBuffer.put(action);

        byteBuffer.put(meterInfo.addr);
        byteBuffer.put(meterInfo.type);
        byteBuffer.put(meterInfo.baud);
//        byteBuffer.put(jiaoyan);
        byteBuffer.put(meterInfo.isPeakvall ? (byte) 0 : 1);
        byteBuffer.put(meterInfo.channel);

        ByteBuffer byteBufferName = ByteBuffer.allocate(16);

        byteBuffer.put(byteBufferName.array());


        return byteBuffer.array();
    }
    /**
     * 表信息：表数量1B+执行1B+地址7B+表类型1B+波特率1B+峰谷1B+通道1B+名称16B，最多16个表（27B *8+1=217B）
     * 拉取表 表数量1B+执行1B+地址7B+表类型1B+数据1B+1B(dummy ) ,
     *
     * 表数量1B 高3位表示拉取数据类型， 低5位表示表数量
     *
     * 执行:01新增,02删除,03修改,04不变，
     表数量（高3位）：0：正常下发操作表数据；1：读取实时数据，2：读取当前数据；3：读取日冻结；4：读取月冻结
     */
    public static byte[] readMeterInfo(MeterInfo meterInfo,Util.readType readType) {

        ByteBuffer byteBuffer = ByteBuffer.allocate(29);
        byte len = 1;
        switch (readType){
            case readRealData:
                len= (byte) Integer.parseInt("00100001",2);
                break;
            case readCuurentData:
                len= (byte) Integer.parseInt("01000001",2);
                break;
            case readDayFreeze:
                len= (byte) Integer.parseInt("01100001",2);
                break;
            case readMonthFreeze:
                len= (byte) Integer.parseInt("10000001",2);
                break;
        }
        byteBuffer.put(len);

        byte action = Util.ACTION_NOT_CHANGE;
//        byteBuffer.put(action);

        byteBuffer.put(meterInfo.addr);
        byteBuffer.put(meterInfo.type);
        byteBuffer.put(meterInfo.baud);//// TODO: 18/2/11
//        byteBuffer.put(jiaoyan);
        byteBuffer.put(meterInfo.isPeakvall ? (byte) 0 : 1);
        byteBuffer.put(meterInfo.channel);

        ByteBuffer byteBufferName = ByteBuffer.allocate(16);

        byteBuffer.put(byteBufferName.array());


        return byteBuffer.array();
    }

    private static String getAddr(byte[] addr) {
        return Util.bytesToHexString(Util.revertOrder(addr));
    }
}
